(function() {
  var calcPath, creepList, moveTowards, removeFromArray, towerList, travelTowards;
  creepList = [];
  towerList = [];
  Crafty.c("Tower", {
    detectAndFire: function() {
      var creep, fireList, targetCreep, _i, _len;
      fireList = [];
      for (_i = 0, _len = creepList.length; _i < _len; _i++) {
        creep = creepList[_i];
        if (this.inRadius(creep)) {
          fireList.push(creep);
        }
      }
      if (fireList.length > 0) {
        targetCreep = this.findClosestCreep(fireList);
        this.shoot(targetCreep);
      }
      return null;
    },
    shoot: function(creep) {
      var bul;
      bul = Crafty.e("2D, DOM, Collision, Bullet");
      bul.bullet(this, creep);
      return null;
    },
    inRadius: function(creep) {
      return Crafty.math.distance(this.x, this.y, creep.x, creep.y) <= this.fireRadius;
    },
    findClosestCreep: function(fireList) {
      var closest, closestdist, targ, targdist, _i, _len;
      closest = fireList[0];
      closestdist = Crafty.math.distance(this.x, this.y, closest.x, closest.y);
      for (_i = 0, _len = fireList.length; _i < _len; _i++) {
        targ = fireList[_i];
        targdist = Crafty.math.distance(this.x, this.y, targ.x, targ.y);
        if (targdist < closestdist) {
          closest = targ;
          closestdist = targdist;
        }
      }
      return closest;
    },
    init: function() {
      this.addComponent("2D, Canvas, Collision");
      towerList.push(this);
      return this;
    },
    tower: function(towerpos, spriteName, cost, firePower, fireRadius, fireRate) {
      this.towerpos = towerpos;
      this.spriteName = spriteName;
      this.cost = cost;
      this.firePower = firePower;
      this.fireRadius = fireRadius;
      this.fireRate = fireRate;
      this.addComponent("2D, DOM, " + this.spriteName);
      this.attr(this.towerpos);
      this.bind("EnterFrame", function() {
        if (Crafty.frame() % this.fireRate === 0) {
          this.detectAndFire();
        }
        return null;
      });
      return this;
    }
  });
  Crafty.c("Creep", {
    damage: function(dam) {
      this.health -= dam;
      if (this.health <= 0) {
        this.die();
      }
      return null;
    },
    die: function() {
      removeFromArray(creepList, this);
      return this.destroy();
    },
    creep: function(sp, speed, start, dest) {
      var dist;
      this.sp = sp;
      this.speed = speed;
      this.start = start;
      this.dest = dest;
      this.addComponent("2D, DOM, " + this.sp + ", Tween");
      this.attr(this.start);
      this.z = 4;
      dist = Crafty.math.distance(this.x, this.y, this.dest.x, this.dest.y);
      console.log(dist);
      console.log(dist / this.speed | 0);
      this.bind("EnterFrame", function() {
        travelTowards(this, this.start, this.dest);
        if (this.y > Crafty.viewport.height || this.y < 0 || this.x < 0 || this.x > Crafty.viewport.width) {
          this.die();
        }
        return null;
      });
      return this;
    },
    init: function() {
      this.health = 100;
      this.addComponent("Collision");
      creepList.push(this);
      return this;
    }
  });
  Crafty.c("Bullet", {
    init: function() {},
    bullet: function(tower, targ) {
      this.attr({
        x: tower.x + tower.w / 2,
        y: tower.y + tower.h / 2,
        w: 2,
        h: 2,
        z: 11,
        speed: 2,
        damagepts: tower.firePower
      });
      this.addComponent("Color").color("blue");
      this.bind("EnterFrame", function() {
        moveTowards(this, targ, this.speed);
        if (this.y > Crafty.viewport.height || this.y < 0 || this.x < 0 || this.x > Crafty.viewport.width) {
          return this.destroy();
        }
      });
      this.onHit("Creep", function(colList) {
        var hitCreep;
        hitCreep = colList[0].obj;
        hitCreep.damage(this.damagepts);
        return this.destroy();
      });
      return null;
    }
  });
  calcPath = function(x1, y1, x2, y2, speed) {
    var dist, pathx, pathy, xdiff, ydiff;
    xdiff = x2 - x1;
    ydiff = y2 - y1;
    dist = Crafty.math.distance(x1, y1, x2, y2);
    pathx = (1.0 * speed * xdiff) / dist;
    pathy = (1.0 * speed * ydiff) / dist;
    return {
      px: pathx,
      py: pathy
    };
  };
  moveTowards = function(obj1, obj2, speed) {
    var path;
    path = calcPath(obj1.x, obj1.y, obj2.x, obj2.y, speed);
    obj1.x += path.px;
    obj1.y += path.py;
    return null;
  };
  removeFromArray = function(array, elem) {
    var index;
    index = array.indexOf(elem);
    if (index !== -1) {
      array.splice(index, 1);
    }
    return null;
  };
  travelTowards = function(obj, start, dest) {
    var path;
    path = calcPath(start.x, start.y, dest.x, dest.y, obj.speed);
    obj.x += path.px;
    obj.y += path.py;
    console.log("" + obj.x + ", " + obj.y);
    return null;
  };
}).call(this);
